<?

/**
 * Tareas class
 *
 * Esta clase maneja las tareas por usuario
 * @author Alejandro Garcia del Rio <alejandro.garciadelrio@elserver.com>
 * @version 1.0
 * @package Tareas
*/
class Tareas extends Core {

	static protected $instancia;
	static protected $opciones = array(
		'rpp' => 100, // Resultados por pagina 
		'filtros' => '', // Filtros para la funcion listar
		'page' => 1, // Numero de pagina por defecto
		'order' => 't.fecha_inicio', // Ordenamiento de listar()
		'order_type' => 'ASC' // Tipo de ordenamiento (ASC/DESC)
	);
	private $count = 0;
	private $paginas = 0;
	private $id_usuario = null;

	/**
	 * Constructor de la clase.
	 * 
	 * @param array $opciones (opcional) Opciones validas para esta clase
	 */
	function __construct ($id_usuario=null, $opciones=null) {
		// Llamo al constructor del parent tambien
		parent::__construct();
		// Guardo las opciones si me definio alguna
		if ($opciones)
			$this->opciones($opciones);
		// Seteo el id de caso
		$this->usuario($id_usuario);
	}

	/**
	 * Setea las opciones 
	 * 
	 * @param array $opciones (opcional) Opciones validas para esta clase. Si esta vacio, funciona como un getter.
	 * @return array $opciones Listado de opciones
	 */
	public function opciones ($opciones=null) {
		return self::$opciones = parent::opciones(self::$opciones, $opciones);
	}

	/**
	 * Devuelve una unica instancia de esta clase
	 * 
	 * @return object Instancia de esta clase
	 */
	public static function getInstance() {
		if (!self::$instancia instanceof self)
			self::$instancia = new self;
		return self::$instancia;
	}

	/**
	 * Setea el id de usuario al que corresponde este acl
	 * 
	 * @param integer $id_usuario (opcional) El id del usuario.
	 * @return integer El id del usuario
	 */
	public function usuario ($id_usuario=null) {

		// Obtengo un objeto de sesion
		$Session = ($this)? $this->Session : Session::getInstance();

		// Si no hay un usuario definido, lo tomo de la sesion
		if (!SSO::logged())
			return ($this)? $this->error("El usuario no esta logueado") : false;

		// Si no hay un usuario definido, lo tomo de la sesion
		if (!$id_usuario && !$this->id_usuario) 
			$id_usuario = $Session->get('usuario.id');

		if ($id_usuario)
			$this->id_usuario = addslashes($id_usuario);

		return $this->id_usuario;
	}

	/**
	 * Agrega una nueva tarea para el usuario actual
	 * 
	 * @param array $tarea Informacion de la tarea a agregar
	 * @param integer $id_usuario (Opcional) Id de usuario de esta tarea
	 * @return object Instancia de esta clase
	 */
	public function agregar ($tarea, $id_usuario=null) {

		// Seteo el id de usuario
		if (($id_usuario) && $this instanceof self)
			$this->usuario($id_usuario);

		// Obtengo el usuario si esta instanciada la clase
		if ($this instanceof self)
			$id_usuario = $this->usuario();

		// No hay tarea definida
		if (!is_array($tarea) || empty($tarea))
			return ($this)? $this->fail('No hay una tarea especificada') : false;

		// Valido que tenga un id de usuario
		if (!$id_usuario)
			return ($this)? $this->fail('No hay un id de usuario especificado') : false;

		// Obtengo un objeto de conexion a la base
		$db = ($this)? $this->db : ez_sql::getInstance();

		// Si no tiene fecha_fin, le pongo una duracion de una hora desde la fecha de inicio
		if (!$tarea['fecha_fin'])
			//$tarea['fecha_fin'] = date("Y-m-d H:i:s", (strtotime($tarea['fecha_inicio'])+(60*60)));
			$tarea['fecha_fin'] = $tarea['fecha_inicio'];

		// Seteo algunos parametros
		unset($tarea['id_tarea']);
		unset($tarea['ctime']);
		unset($tarea['pendiente']);
		$tarea['id_usuario'] = $id_usuario;
		$tarea['fecha_inicio'] = date("Y-m-d H:i:s", strtotime($tarea['fecha_inicio']));
		$tarea['fecha_fin'] = date("Y-m-d H:i:s", strtotime($tarea['fecha_fin']));

		// Inserto la tarea
		$id_tarea = $db->insert("tareas", $tarea);
		
		// Asocio la tarea
		$db->insert("tareas_casos", array('id_tarea' => $id_tarea, 'id_caso' => $tarea['id_caso']));

		// Creo el evento en Google Calendar
		// $GCalendar = new GCalendar($id_usuario);
		// $id_gcalendar = $GCalendar->agregar($tarea);

		// Almaceno que id_gcalendar tiene esta tarea
		$db->update('tareas', array('id_tarea' => $id_tarea, 'id_gcalendar' => $id_gcalendar));

		// Registro este evento en el log del caso
		if ($tarea['id_caso'])
			CasoLog::agregar("Se agrego una tarea ($id_tarea)", 4, $tarea['id_caso']);

		return $id_tarea;
	}


	/**
	 * Lista las tareas
	 * 
	 * @param $opciones (Opcional) Opciones de esta clase 
	 * @return object Instancia de esta clase
	 */
	public function listar ($opciones=null) {

		// Obtengo el objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();

		// Obtengo un objeto de sesion
		$Session = ($this)? $this->Session : Session::getInstance();

		// Obtengo el usuario logueado
		if ( !($id_usuario = $Session->get('usuario.id')) )
			return ($this)? $this->fail('No estas logueado') : false;

		// Seteo las opciones
		$opciones = ($this instanceof self)? $this->opciones($opciones) : self::opciones($opciones);
		
		// Agrego los filtros
		$and = $opciones['filtros'];
			
		// Query base
		$query = "SELECT SQL_CALC_FOUND_ROWS t.*
					FROM tareas t
					WHERE 1=1 $and
					ORDER BY ".$opciones['order']." ".$opciones['order_type']." 
					LIMIT ".(($opciones['page']-1)*$opciones['rpp']).", ".$opciones['rpp'];
		
		// Ejecuto el query
		$tareas = $db->get_results($query);
		
		//$db->debug();
		
		// Calculo la cantidad de resultados
		$count = $db->get_var('SELECT FOUND_ROWS()');
		if ($this instanceof self)
			$this->count = $count;

		$paginas = ($this instanceof self)? $this->paginas() : self::paginas($count, $opciones['rpp']);

		return array('paginas' => $paginas, 'resultados' => $count, 'data' => $tareas);
	}

	/**
	 * Devuelve cuantos resultados hay en la consulta
	 * 
	 * Los resultados son cargados previamente por la funcion listar
	 * @return integer Cantidad de resultados
	 */
	public function count () {
		return $this->count;
	}

	/**
	 * Devuelve la cantidad de paginas que devolvio la consulta
	 * 
	 * Los resultados son cargados previamente por la funcion listar
	 * @param array $count (Opcional) Cantidad total se resultados
	 * @param array $rpp (Opcional) Cantidad de resultados por pagina
	 * @return integer Cantidad de resultados
	 */
	public function paginas ($count=null, $rpp=null) {

		$rpp = (!$rpp)? self::$opciones['rpp'] : $rpp;
		$count = (!$count && $this instanceof self)? $this->count() : $count;

		// No se puede dividir por 0
		if ($rpp == 0)
			return 0;

		return ceil($count/$rpp);
	}

	/**
	 * Devuelve el contenido de una tarea
	 * 
	 * @param $id_tarea integer El id de tarea a eliminar
	 * @return array
	 */
	public function get ($id_tarea) {

		// Saneamiento de variables
		$id_tarea = addslashes($id_tarea);

		// Obtengo un objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();

		return $db->get_row("SELECT * FROM tareas WHERE id_tarea = $id_tarea");
	}

	/**
	 * Elimina una tarea para el usuario actual
	 * 
	 * @param $id_tarea integer El id de tarea a eliminar
	 * @return object Instancia de esta clase
	 */
	public function eliminar ($id_tarea) {

		// Saneamiento de variables
		$id_tarea = addslashes($id_tarea);

		// Obtengo un objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();

		// Obtengo un objeto de sesion
		$Session = ($this)? $this->Session : Session::getInstance();

		// Obtengo la tarea a eliminar
		$tarea = ($this)? $this->get($id_tarea) : self::get($id_tarea);
		if (!$tarea)
			return ($this)? $this->fail('No se encontro la tarea') : false;

		// Obtengo el usuario logueado
		if ( !($id_usuario = $Session->get('usuario.id')) )
			return ($this)? $this->fail('No estas logueado') : false;

		// Valido que el usuario de la tarea sea el logueado
		if ($id_usuario != $tarea['id_usuario'])
			return ($this)? $this->fail('No podes eliminar una tarea que no te corresponda') : false;

		// Valido que no este marcada como realizada
		if ($tarea['pendiente'] != 1)
			return ($this)? $this->fail('No se puede eliminar una tarea realizada') : false;

		// Elimino la tarea
		$db->query("DELETE FROM tareas WHERE id_tarea = $id_tarea");

		// La elimino de Google Calendar
		// $GCalendar = new GCalendar($id_usuario);
		// $id_gcalendar = $GCalendar->eliminar($tarea['id_gcalendar']);

		// Registro este evento en el log del caso
		if ($tarea['id_caso'])
			CasoLog::agregar("Se elimino una tarea ($id_tarea)", 4, $tarea['id_caso']);

		return true;
	}

	/**
	 * Modifica una tarea del usuario actual
	 * 
	 * @param $tarea array Datos a modificar en esta tarea
	 * @param $id_tarea integer El id de tarea a modificar
	 * @return object Instancia de esta clase
	 */
	public function modificar ($tarea, $id_tarea) {

		// Saneamiento de variables
		$id_tarea = addslashes($id_tarea);

		// Obtengo un objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();

		// Obtengo un objeto de sesion
		$Session = ($this)? $this->Session : Session::getInstance();

		// Obtengo la tarea a modificar
		$old_tarea = self::get($id_tarea);
		if (!$old_tarea)
			return ($this)? $this->fail('No se encontro la tarea') : false;

		// Obtengo el usuario logueado
		if ( !($id_usuario = $Session->get('usuario.id')) )
			return ($this)? $this->fail('No estas logueado') : false;

		// Valido que el usuario de la tarea sea el logueado
		if ($id_usuario != $old_tarea['id_usuario'])
			return ($this)? $this->fail('No podes eliminar una tarea que no te corresponda') : false;

		// Valido que no este marcada como realizada
		if ($old_tarea['pendiente'] != 1)
			return ($this)? $this->fail('No se puede modificar una tarea realizada') : false;

		// Campos habilitados para modificacion
		$campos = array('id_caso', 'fecha_inicio', 'fecha_fin', 'titulo', 'descripcion', 'pendiente');

		// Solo dejo los campos habilitados para modificacion
		if (is_array($tarea) && !empty($tarea))
			foreach ($tarea as $t)
				if (!isset($campos[$t]))
					unset($tarea[$t]);
		$tarea['id_tarea'] = $id_tarea;

		// Ejecuto la modificacion
		$db->update('tareas', $tarea);

		// Ejecuto la modificacion tambien en GCalendar
		// $GCalendar = new GCalendar();
		// $GCalendar->modificar($old_tarea['id_gcalendar'], array_merge($old_tarea, $tarea));

		return true;
	}

	/**
	 * Marca una tarea como realizada para el usuario actual
	 * 
	 * @return object Instancia de esta clase
	 */
	public function hecho ($id_tarea) {

		// Saneamiento de variables
		$id_tarea = addslashes($id_tarea);

		// Obtengo un objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();

		// Obtengo el id_gcalendar de esta tarea
		// $id_gcalendar = $db->get_var("SELECT id_gcalendar FROM tareas WHERE id_tarea = '$id_tarea'");

		// Marco la tarea como hecha en Google Calendar
		// $GCalendar = new GCalendar();
		// $newGCalendarEvent = $GCalendar->hecho($id_gcalendar);

		// Modifico la tarea
		$db->update('tareas', array('id_tarea' => $id_tarea, 'pendiente' => 0, 'id_gcalendar' => $newGCalendarEvent));

		// Registro este evento en el log del caso
		$tarea = self::get($id_tarea);
		CasoLog::agregar("Se realizo una tarea ($id_tarea)", 4, $tarea['id_caso']);

		return true;
	}
	

	
	/**
	 * Devuelve los casos asociados con una tarea
	 * 
	 * @id_tarea integer ID de caso
	 * @return array Listado de casos
	 */
	public function casos_asociados ($id_tarea) {
		
		// Saneamiento de variables
		$id_tarea = addslashes($id_tarea);

		// Obtengo un objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();
		
		return $db->get_results("SELECT c.*, tc.id_tarea FROM casos c JOIN tareas_casos tc ON c.id_caso = tc.id_caso WHERE id_tarea = '$id_tarea'");
	}
	
	
	
	/**
	 * Asocia un caso con una tarea existente
	 * 
	 * @param integer ID de caso
	 * @param integer ID de tarea
	 */
	public function asociar ($id_caso, $id_tarea) {
		
		// Saneamiento de variables
		$id_tarea = addslashes($id_tarea);

		// Obtengo un objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();
		
		// Asocio la tarea
		$db->insert("tareas_casos", array('id_tarea' => $id_tarea, 'id_caso' => $id_caso));
		
		return 1;
		
	}
	
	
	
	/**
	 * Devuelve un JSON de tareas con el formato requerido por FullCalendar
	 * 
	 */
	public function fullcalendar () {

		// Obtengo un objeto de sesion
		$Session = ($this)? $this->Session : Session::getInstance();
	
		// Obtengo el usuario logueado
		if ( !($id_usuario = $Session->get('usuario.id')) )
			return ($this)? $this->fail('No estas logueado') : false;
		
		// Seteo las opciones
		$opciones = array('filtros' => 'AND id_usuario = ' . $id_usuario . ' OR id_area = ' . $Session->get('usuario.id_area'));
		
		// Pido el listado
		$tareas = ($this instanceof self)? $this->listar($opciones) : self::listar($opciones);
		
		foreach ($tareas['data'] as $key_tarea => $value_tarea) {
			// Datos basicos
			$result[$key_tarea]['title'] = $value_tarea['titulo'];
			$result[$key_tarea]['start'] = strtotime($value_tarea['fecha_inicio']);
			$result[$key_tarea]['end'] = strtotime($value_tarea['fecha_fin']);
			$result[$key_tarea]['allDay'] = false;
			// Defino el link segun si es pendiente o realizada
			$result[$key_tarea]['url'] = '/sic/agenda/' . (($value_tarea['pendiente']) ? 'pendientes' : 'archivo') . '/ver/' . $value_tarea['id_tarea'];
			// Defino el color
			$result[$key_tarea]['color'] = 'red'; // tarea personal
			if (!$value_tarea['id_area'])
				$result[$key_tarea]['color'] = 'blue'; // tarea del area
			if (!$value_tarea['pendiente'])
				$result[$key_tarea]['color'] = 'grey'; // tarea archivada
		}
		
		return $result;		
	}
	
	

	
	
}

?>
